function [lpriormin,xmax,exitflag,output,Hx]=...
    mcmc_fmincon(x0,parvec,parposest,funcmod,prpar,prss,solveopt,addsol,ssposest,estimopt)
% ======================================================================
% ESTIMA_FMINCON.M
%
% Uses FMINCON optimization routine 
% Function underlying minization is identical to LMJ_POSTOPTIM.m and is
% included as a nested function. Only difference is that the parameter does 
% not go through the transformation matrix since the bounds are directly applied to the optimization 
% procedure using BOUNDS loaded from prior. 
% Hence X0 is an unstransformed starting value 
% format.  
%
% Input 
% ------
% Note:     Input PRPAR.LBND and PRPAR.UBND is truncated inside code 
% ESTIMOPT  Has all the settings for the optimization  
% Output 
% ------
% XMIN      in MIN  space for compatibility with GENSYSOUTPUT 
% XMODEL    in MODEL space  
% LPOSTMIN  stil *(-1) 
% Using OUTPUT, will display end message in a DIARY file created in the
% output subdirectory 
% 
% Alejandro Justiniano  January 11 2008 
% 1/13/09 Added LBND and UBND in priordens s.t. can work with the truncated
% BETA 
% =======================================================================
%clear x lpostd; 
if any(imag(x0)~=0);error('Initial guess X0 cannot be imaginary');end
% Truncate bounds 
% ========================================================================
% Define the bounds for the optimization to ensure compatibility with
% INDMAT. Also check suggested starting point is within bounds, else adjust
% BOUNDS should NOT be truncated 
% ========================================================================
offset=1e-8; 
bounds=[prpar.lbnd(parposest)+offset prpar.ubnd(parposest)-offset]; 
check1=find(x0 < bounds(:,1));
check2=find(x0 > bounds(:,2)); 
if ~isempty(check1) 
    check1_disc=abs(x0(check1)-prpar.lbnd(check1)); 
    if max(check1_disc) > 0.01;error('Starting value is below lower bound');end
    x0(check1)=x0(check1)+check1_disc+offset; 
end 
if ~isempty(check2) 
    check2_disc=abs(x0(check2)-prpar.ubnd(check2)); 
    if max(check2_disc) > 0.01;
        dispaj('Positions ',check2(:),' above upper bound')
        error('Starting value is above upper bound')
    end
    x0(check2)=x0(check2)-check2_disc-offset;
end 
clear check* offset; 
% ========================================================================
% Begin Optimization  
% ========================================================================
tic;
[xmax,lpriormin,exitflag,output,junk,gradx,Hx]=fmincon(@lmj_prioroptimsub,x0,[],[],[],[],bounds(:,1),bounds(:,2),[],estimopt);
% ============================================
%           NESTED FUNCTION
% ============================================
    function lpriord=lmj_prioroptimsub(x) 
        lpriord=1e20;
        parvec(parposest)=x;        
        [G1,impact,C,eu,SDX,ZZ,junk,ssvec]=feval(funcmod,parvec,solveopt,addsol);
        if isequal(eu,[1;1])==0;disp('Non existence or uniqueness');return;end
     
        % 2. Prior for the parameters 
        % 3. Prior for the SS 
        if ~isempty(ssposest)
            lpriord_ss = sum(priordens(ssvec(ssposest), prss.prior, prss.alphap, prss.betap, prss.lbnd, prss.ubnd));
        else
            lpriord_ss=0;
        end
        lpriord_par=sum(priordens(parvec,prpar.prior,prpar.alphap,prpar.betap,prpar.lbnd,prpar.ubnd));
        if isinf(abs(lpriord))==1;disp('Prior is INF');return;end
        clear lpriord; 
        lpriord=-(lpriord_par+lpriord_ss); 
        %disp(['LPOSTD=',num2str(lpostd)]); 
    end
end